using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using SurveySez.Model;
using SurveySez.NavigationModel;
using UpdateControls.XAML;

namespace SurveySez.ViewModel.Editor
{
    public class SurveyDetailsViewModel
	{
		private Survey _survey;
		private EditorNavigationModel _navigation;

		public SurveyDetailsViewModel(Survey survey, EditorNavigationModel navigation)
		{
			_navigation = navigation;
			_survey = survey;
		}

		public string Question
		{
			get { return _survey.Question; }
			set { _survey.Question = value; }
		}

		public IEnumerable<ResponseViewModel> Answers
		{
			get
			{
				return _survey.Responses
					.OrderBy(response => response.Order)
					.Select(response => new ResponseViewModel(response));
			}
		}

		public ResponseViewModel SelectedAnswer
		{
			get
			{
				return _navigation.SelectedResponse == null
					? null
					: new ResponseViewModel(_navigation.SelectedResponse);
			}
			set
            {
            	_navigation.SelectedResponse = value == null
					? null
					: value.Response;
            }
		}

		public ICommand NewAnswer
		{
			get
			{
				return MakeCommand
					.Do(() => _navigation.SelectedResponse = _survey.NewResponse());
			}
		}

		public ICommand DeleteAnswer
		{
			get
			{
				return MakeCommand
					.When(() => _navigation.SelectedResponse != null)
					.Do(() => _navigation.SelectedResponse.Delete());
			}
		}

		public ICommand MoveAnswerUp
		{
			get
			{
				return MakeCommand
					.When(() =>
						_navigation.SelectedResponse != null &&
						_survey.Responses.Any(response => response.Order < _navigation.SelectedResponse.Order))
					.Do(() =>
					{
						float priorOrder = _survey.Responses
							.Where(response => response.Order < _navigation.SelectedResponse.Order)
							.Max(response => response.Order);
						float earlierOrder = _survey.Responses
							.Where(response => response.Order < priorOrder)
							.Max(response => (float?)response.Order) ?? 0.0f;

						_navigation.SelectedResponse.Order = (priorOrder + earlierOrder) / 2.0f;
					});
			}
		}

		public ICommand MoveAnswerDown
		{
			get
			{
				return MakeCommand
					.When(() =>
						_navigation.SelectedResponse != null &&
						_survey.Responses.Any(response => response.Order > _navigation.SelectedResponse.Order))
					.Do(() =>
					{
						float nextOrder = _survey.Responses
							.Where(response => response.Order > _navigation.SelectedResponse.Order)
							.Min(response => response.Order);
						float laterOrder = _survey.Responses
							.Where(response => response.Order > nextOrder)
							.Min(response => (float?)response.Order) ?? nextOrder + 2.0f;

						_navigation.SelectedResponse.Order = (nextOrder + laterOrder) / 2.0f;
					});
			}
		}
	}
}
